extends Node

signal on_game_start()
# UI
var now_level = 1 #当前关卡
var shake = 1.0 #振动幅度
var canvas_layer: CanvasLayer
# 光标
var cursor: TextureRect
var pause_state = false #暂停状态
var is_game_start = false #游戏是否开始
var player: Player = Player.new()
var boss
var freeze_frame = false
var player_init_position = Vector2.ZERO
var boss_init_position = Vector2.ZERO
enum GUN_CHANGE_TYPE { #切枪类型
	CHANGE, #切换枪械
	RELOAD #切换子弹
}

var weapon_list = {
	"0" = preload("res://entities/gun/custom_gun/custom_gun.tscn"),
	"1" = preload("res://scenes/entities/sword/sword.tscn")
}
var temp_am_list = []

const fluent_tip_path = "res://entities/ui/fluent_tip(流畅提示)/fluent_tip.tscn"
const info_show_label = preload("res://entities/ui/info_show/info_show.tscn")
const tip = preload("res://entities/ui/tip/tip.tscn")

# 批量伤害合并系统
var pending_damage: Dictionary = {}  # target -> {damage: float, color: Color, timer: float, is_boss: bool, is_critical: bool}
const DAMAGE_MERGE_TIME = 0.01  # 60ms内合并伤害

func game_start():
	is_game_start = true
	emit_signal("on_game_start")

func _process(delta):
	if Input.is_action_just_pressed("重启游戏"):
		EventBus.buss.clear()
		get_tree().reload_current_scene()
	# 处理批量伤害合并
	var targets_to_remove = []
	for target in pending_damage:
		# 检查目标是否仍然有效
		if target == null or not is_instance_valid(target):
			targets_to_remove.append(target)
			continue
			
		pending_damage[target].timer -= delta
		if pending_damage[target].timer <= 0:
			# 显示合并后的伤害
			var data = pending_damage[target]
			var ins = info_show_label.instantiate()
			ins.set_number(data.damage)
			ins.position = Vector2.ZERO
			# 直接添加到目标对象
			target.add_child(ins)
			# 根据目标对象的scale调整文字大小
			var scale_factor = max(target.scale.x, target.scale.y)
			ins.set_scale_factor(scale_factor)
			ins.set_color(data.color)
			ins.set_critical(data.is_critical)
			targets_to_remove.append(target)
	
	for target in targets_to_remove:
		pending_damage.erase(target)

var camera
## 屏幕抖动
func camera_shake(_scale = Vector2(0.99, 0.99), _offset = Vector2(0.2, 0.2)):
	if not camera:
		camera = get_viewport().get_camera_2d()
	var tween = create_tween()
	tween.tween_property(camera, "offset", Vector2.ZERO, 0.12).from(_offset)
	tween.parallel().tween_property(camera, "zoom", Vector2(1.00, 1.00), 0.12).from(_scale)
	
#信息颜色
func show_string_label_c(text, target: Node2D, color = Color.WHITE):
	var ins = info_show_label.instantiate()
	ins.position = Vector2.ZERO
	ins.set_string(text)
	# 直接添加到目标对象
	target.add_child(ins)
	# 根据目标对象的scale调整文字大小
	var scale_factor = max(target.scale.x, target.scale.y)
	ins.set_scale_factor(scale_factor)
	ins.set_color(color)
	
#伤害数字颜色 - 带批量合并
func show_hit_label_c(num, target: Node2D, color = Color.WHITE, is_critical = false):
	# 检查目标是否有效
	if target == null or not is_instance_valid(target):
		return
		
	# 检查是否应该合并伤害
	if pending_damage.has(target):
		# 合并伤害到同一个目标
		pending_damage[target].damage += num
		pending_damage[target].timer = DAMAGE_MERGE_TIME
		# 如果有一个是暴击，就标记为暴击
		if is_critical:
			pending_damage[target].is_critical = true
	else:
		# 为新的目标创建独立的伤害记录
		pending_damage[target] = {
			"damage": num,
			"color": color,
			"timer": DAMAGE_MERGE_TIME,
			"is_boss": false,
			"is_critical": is_critical
		}
		# 暴击时触发屏幕震动
		if is_critical:
			camera_shake(Vector2(0.90, 0.90), Vector2(1.0, 1.0))
		else:
			camera_shake()
			
## 展示中间的提示
func show_tip(text):
	var ins = tip.instantiate()
	ins.set_string(text)
	get_tree().get_first_node_in_group("ui").add_child(ins)

func _freeze_frame(scale):
	if not freeze_frame and scale > 0:
		# 冻结帧
		pass
		#freeze_frame = true
		# 将时间比例设置为0.1
		#Engine.time_scale = scale
	
func show_toast(msg, time = 1):
	if canvas_layer:
		canvas_layer.show_toast(msg, time)

## 多次加锁
var pause: Array = []
## 设置旋转光标状态
func cross_hair_change(status: bool):
	cursor = get_tree().get_first_node_in_group("cursor")
	if status:
		pause.pop_back()
		if pause.is_empty():
			Input.mouse_mode = Input.MOUSE_MODE_CONFINED_HIDDEN
			get_tree().paused = true
			GameManager.ui_active = false
			cursor.visible = status
	else:
		pause.append("")
		Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
		get_tree().paused = false
		GameManager.ui_active = true
		cursor.visible = status
		
func next_level():
	now_level += 1
	
func init_player():
	player = PlayerDataManager.player.instantiate()
	get_tree().current_scene.add_child(player)
	player.global_position = player_init_position
	
func init_boss():
	boss = BossDataManager.get_boss().instantiate()
	get_tree().current_scene.call_deferred("add_child", boss)
	boss.global_position = boss_init_position

func init_game():
	print("初始化游戏")
	# 重置文字显示实例计数器
	reset_text_counters()
	# 清空待合并伤害
	pending_damage.clear()
	if not player:
		init_player()
	else:
		player.global_position = player_init_position
		player.init_game()
	init_boss()
	return

## 重置文字显示实例计数器
func reset_text_counters():
	# 重置所有文字显示组件的实例计数器
	if info_show_label:
		var script = info_show_label.get_script()
		if script and script.has_method("reset_counter"):
			script.reset_counter()
	if tip:
		var script = tip.get_script()
		if script and script.has_method("reset_counter"):
			script.reset_counter() 

func mouse_ignore(node):
	if node.has_method("mouse_filter"):
		node.mouse_filter(false)
	for child in node.get_children():
		if child.has_method("mouse_filter"):	
			mouse_ignore(child)

## 添加装备属性到玩家
func add_to_player(pandora: PandoraEntity):
	ItemManager.add_item_buff(pandora)
	set_player_stats_value("additional_move_speed", pandora.get_integer("move_speed"))
	set_player_stats_value("additional_attack_speed", pandora.get_integer("attack_speed"))
	set_player_stats_value("additional_damage", pandora.get_float("base_damage"))
	set_player_stats_value("critical_chance", pandora.get_integer("critical_chance"))
	set_player_stats_value("max_hp", pandora.get_integer("hp"))
	set_player_stats_value("max_mp", pandora.get_integer("mp"))	
	set_player_stats_value("add_attack_probability", pandora.get_float("add_attack_probability"))
	set_player_stats_value("add_hp_probability", pandora.get_float("add_hp_probability"))	
	set_player_stats_value("add_mp_probability", pandora.get_float("add_mp_probability"))	
	set_player_stats_value("add_coin_probability", pandora.get_float("add_coin_probability"))	
	set_player_stats_value("add_exp_probability", pandora.get_float("add_exp_probability"))	
	set_player_stats_value("cooldown_reduction", pandora.get_float("cooldown_reduction"))
	## 百分比经验加成
	set_player_stats_value("exp_bonus", pandora.get_float("exp_bonus"))
	set_player_stats_value("health_regen", pandora.get_float("health_regen"))
	set_player_stats_value("mp_regen", pandora.get_float("mp_regen"))
## 减去装备属性到玩家
func minus_to_player(pandora: PandoraEntity):
	ItemManager.remove_item_buff(pandora)
	set_player_stats_value("additional_move_speed", -pandora.get_integer("move_speed"))
	set_player_stats_value("additional_attack_speed", -pandora.get_integer("attack_speed"))
	set_player_stats_value("additional_damage", -pandora.get_float("base_damage"))
	set_player_stats_value("critical_chance", -pandora.get_integer("critical_chance"))
	set_player_stats_value("max_hp", -pandora.get_integer("hp"))
	set_player_stats_value("max_mp", -pandora.get_integer("mp"))	
	set_player_stats_value("add_attack_probability", -pandora.get_float("add_attack_probability"))
	set_player_stats_value("add_hp_probability", -pandora.get_float("add_hp_probability"))	
	set_player_stats_value("add_mp_probability", -pandora.get_float("add_mp_probability"))	
	set_player_stats_value("add_coin_probability", -pandora.get_float("add_coin_probability"))	
	set_player_stats_value("add_exp_probability", -pandora.get_float("add_exp_probability"))	
	set_player_stats_value("cooldown_reduction", -pandora.get_float("cooldown_reduction"))
	set_player_stats_value("exp_bonus", -pandora.get_float("exp_bonus"))
	set_player_stats_value("health_regen", -pandora.get_float("health_regen"))
	set_player_stats_value("mp_regen", -pandora.get_float("mp_regen"))
	
const ROLL_RARITIES := {
	1:  [1],
	2:  [1],
	3:  [1],
	4:  [1],
	5:  [1, 2],
	6:  [1, 2],
	7:  [1, 2],
	8:  [1, 2],
	9:  [1, 2, 3],
	10:  [1, 2, 3],
	11:  [1, 2, 3],
	12:  [1, 2, 3],
	13:  [1, 2, 3, 4],
	14:  [1, 2, 3, 4],
	15:  [1, 2, 3, 4],
	16:  [1, 2, 3, 4, 5],
	17:  [1, 2, 3, 4, 5],
	18:  [1, 2, 3, 4, 5]
}
const ROLL_CHANCES := {
	1: [1.0],
	2: [1.0],
	3: [1.0],
	4: [1.0],
	5: [8.0, 2.0],
	6: [7.0, 3.0],
	7: [6.0, 4.0],
	8: [5.0, 5.0],
	9: [4.5, 4.5, 1.0],
	10: [4.0, 4.0, 2.0],
	11: [3.5, 3.5, 3.0],
	12: [3.0, 3.0, 4.0],
	13: [2.5, 2.5, 4.0, 1.0],
	14: [1.5, 2.5, 4.0, 2.0],
	15: [0.5, 2.0, 4.5, 3.0]
	#16: [0.0, 2.0, 3.0, 4.0, 1.0],
	#17: [0.0, 0.0, 2.5, 4.5, 3.0],
	#18: [0.0, 0.0, 0.0, 5.0, 5.0]
}

## 根据等级来获取稀有度
func get_random_rarity_for_level() -> int:
	var rng = RandomNumberGenerator.new()
	var level = min(get_player_stats_value("level"), ROLL_CHANCES.size())
	var array: Array = ROLL_RARITIES[level]
	var weights: PackedFloat32Array = PackedFloat32Array(ROLL_CHANCES[level])
	return array[rng.rand_weighted(weights)]

## 为玩家属性设定值
func set_player_stats_value(_name: String, _value):
	match _name:
		"current_hp":
			var max_hp = player.player_stats.get_float("max_hp")
			var current_hp = player.player_stats.get_float("current_hp")
			if current_hp + _value > max_hp:
				_value = max_hp - current_hp
		"current_mp":
			var max_mp = player.player_stats.get_float("max_mp")
			var current_mp = player.player_stats.get_float("current_mp")
			if current_mp + _value > max_mp:
				_value = max_mp - current_mp
	if _value is float:
		player.player_stats.set_float(_name, player.player_stats.get_float(_name) + _value)
	elif _value is int:
		player.player_stats.set_integer(_name, player.player_stats.get_integer(_name) + _value)
	elif _value is String:
		player.player_stats.set_string(_name, _value)
	elif _value is bool:
		player.player_stats.set_bool(_name, _value)

## 获取玩家的值
func get_player_stats_value(_name: String):
	return player.player_stats.get_value(_name)

## 移除节点上的脚本	
func remove_script(node: Node):
	node.set_script(null)
	for child in node.get_children():
		remove_script(child)

func get_item_info(item_stats: PandoraEntity):
	var item_dict = {}
	item_dict["id"] = item_stats.get_entity_id()
	item_dict["index"] = item_stats.get_entity_id()
	item_dict["name"] = item_stats.get_entity_name()
	item_dict["icon"] = item_stats.get_resource("item_texture").resource_path
	item_dict["stuck_size"] = 1
	item_dict["type"] = "武器"
	item_dict["info"] = item_stats.get_string("description")
	item_dict["level"] = item_stats.get_integer("level")
	return item_dict

func show_fluent_tip(text: String):
	var tscn = load(fluent_tip_path).instantiate()
	tscn.A_text = text
	EventBus.push_event("show_fluent_tip", tscn)
